#!/usr/bin env python
# -*- coding: utf-8 -*-
###########################################################################
#   Copyright (C) 2008 by Serj Poltavsky                                  #
#   serge.uliss at gmail.com                                              #
#                                                                         #
#   This program is free software; you can redistribute it and/or modify  #
#   it under the terms of the GNU General Public License as published by  #
#   the Free Software Foundation; either version 3 of the License, or     #
#   (at your option) any later version.                                   #
#                                                                         #
#   This program is distributed in the hope that it will be useful,       #
#   but WITHOUT ANY WARRANTY; without even the implied warranty of        #
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         #
#   GNU General Public License for more details.                          #
#                                                                         #
#   You should have received a copy of the GNU General Public License     #
#   along with this program. If not, see <http://www.gnu.org/licenses/>   #
###########################################################################

import os
import sys
import select
import subprocess

from convert import Convert, ConvertError

class EmptySound(object):
    def __init__(self, seconds = 10):
        self.seconds = int(seconds)
        self.__format = 'ac3'

    def save(self, filename):
        cmd = ["ffmpeg", "-ar", "48000", "-t", str(self.seconds),
            "-f", "s16le", "-acodec", "pcm_s16le",
            "-i", "/dev/zero", "-ab", "64K", "-ar", "48000", "-f", "ac3",
            "-acodec", "ac3", "-y", filename]

        if __debug__:
            print >>sys.stderr, "Generating empty sound..."
            print >>sys.stderr, " ".join(cmd)

        ret = subprocess.call(cmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
        if ret != 0:
            raise ConvertError('Error while generating empty sound')

class SoundConvert(Convert):
    def __init__(self, src, dest, opt=None):
        Convert.__init__(self, src, dest)
        self.bitrate = 192
        self.duration = 0

    def convert(self):
        if not self.is_src_exists():
            raise RuntimeError('Audio source file not exists: "%s"' % self.src)

        cmd = ["ffmpeg", "-i", self.src, "-y", "-ar", "48000", "-ab", str(self.bitrate) + 'k', self.dest]

        if __debug__:
            print >>sys.stderr, "Converting audio \"%s\"..." % os.path.basename(self.src)
            print >>sys.stderr, " ".join(cmd)

        run = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        self.__progress(run.stderr)
        self.convert_wait(run, 'Error while converting audio')

    def __progress(self, stream):
        lastline = ''
        blockread = False
        while True:
            data = select.select([stream.fileno()],[],[])
            if blockread:
                if self.__read_progress(stream) is None:
                    print ''
                    break
                else:
                    continue

            char = stream.read(1)
            if char == '':
                # EOF
                break
            elif char == '\n':
                self.__parse_duration(lastline)
                blockread = self.__is_progress_begins(lastline)
                lastline = ''
            else:
                lastline += char

    def __read_progress(self, stream):
        blockread_sz = 53
        s = stream.read(blockread_sz)
        if s == '':
            #EOF
            return None
        pos = s.find('time=')
        if pos != -1:
            done = s[pos:].split()[0].split('=')[1]
            self.progress_hook(float(done)*100/float(self.duration))
        return True

    def __parse_duration(self, line):
        key = 'Duration: '
        pos = line.find(key)
        if pos == -1:
            return
        dur_lst = line[pos + len(key):].split(', ')[0].split(':')
        #format ['00', '00', '00.00']
        self.duration = int(dur_lst[0]) * 3600 + int(dur_lst[1]) * 60 + int(dur_lst[2][0:2])

    def __is_progress_begins(self, line):
        return line.startswith('Press')
